home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Scout-src.lha / source / objects / scout_semaphores.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-17  |  16.3 KB  |  456 lines

  1. /**
  2.  * Scout - The Amiga System Monitor
  3.  *
  4.  *------------------------------------------------------------------
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOse->  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * You must not use this source code to gain profit of any kind!
  21.  *
  22.  *------------------------------------------------------------------
  23.  *
  24.  * @author Andreas Gelhausen
  25.  * @author Richard Körber <rkoerber@gmx.de>
  26.  */
  27.  
  28. #include "system_headers.h"
  29.  
  30. struct SemaphoresCallbackUserData {
  31.     APTR ud_List;
  32.     ULONG ud_Count;
  33. };
  34.  
  35. static __asm __saveds LONG semalist_con2func(register __a2 Object *obj, register __a1 struct NList_ConstructMessage *msg, register __a0 struct Hook *hook)
  36. {
  37.     return AllocListEntry(msg->pool, msg->entry, sizeof(struct SemaphoreEntry));
  38. }
  39.  
  40. MakeHook(semalist_con2hook, semalist_con2func);
  41.  
  42. static __asm __saveds LONG semalist_des2func(register __a2 Object *obj, register __a1 struct NList_DestructMessage *msg, register __a0 struct Hook *hook)
  43. {
  44.     FreeListEntry(msg->pool, &msg->entry);
  45.  
  46.     return 0;
  47. }
  48.  
  49. MakeHook(semalist_des2hook, semalist_des2func);
  50.  
  51. static __asm __saveds LONG semalist_dsp2func(register __a2 Object *obj, register __a1 struct NList_DisplayMessage *msg, register __a0 struct Hook *hook)
  52. {
  53.     struct SemaphoreEntry *se = (struct SemaphoreEntry *)msg->entry;
  54.  
  55.     if (se) {
  56.         msg->strings[0] = se->se_Address;
  57.         msg->strings[1] = se->se_Name;
  58.         msg->strings[2] = se->se_Pri;
  59.         msg->strings[3] = se->se_NestCount;
  60.         msg->strings[4] = se->se_QueueCount;
  61.         msg->strings[5] = se->se_Owner;
  62.     } else {
  63.         msg->strings[0] = "Address";
  64.         msg->strings[1] = "ln_Name";
  65.         msg->strings[2] = "ln_Pri";
  66.         msg->strings[3] = "ss_NestCount";
  67.         msg->strings[4] = "ss_QueueCount";
  68.         msg->strings[5] = "ss_Owner";
  69.         msg->preparses[0] = MUIX_B;
  70.         msg->preparses[1] = MUIX_B;
  71.         msg->preparses[2] = MUIX_B;
  72.         msg->preparses[3] = MUIX_B;
  73.         msg->preparses[4] = MUIX_B;
  74.         msg->preparses[5] = MUIX_B;
  75.     }
  76.  
  77.     return 0;
  78. }
  79.  
  80. MakeHook(semalist_dsp2hook, semalist_dsp2func);
  81.  
  82. static LONG semalist_cmp2colfunc( struct SemaphoreEntry *se1,
  83.                                 struct SemaphoreEntry *se2,
  84.                                 ULONG column )
  85. {
  86.     LONG pri1, pri2;
  87.  
  88.     switch (column) {
  89.         case 0: return stricmp(se1->se_Address, se2->se_Address);
  90.         case 1: return stricmp(se1->se_Name, se2->se_Name);
  91.         case 2: IsDec(se1->se_Pri, &pri1); IsDec(se2->se_Pri, &pri2); return pri2 - pri1;
  92.         case 3: return stricmp(se1->se_NestCount, se2->se_NestCount);
  93.         case 4: return stricmp(se1->se_QueueCount, se2->se_QueueCount);
  94.         case 5: return stricmp(se1->se_Owner, se2->se_Owner);
  95.     }
  96. }
  97.  
  98. static __asm __saveds LONG semalist_cmp2func(register __a2 Object *obj, register __a1 struct NList_CompareMessage *msg, register __a0 struct Hook *hook)
  99. {
  100.     LONG cmp;
  101.     struct SemaphoreEntry *se1, *se2;
  102.     ULONG col1, col2;
  103.  
  104.     se1 = (struct SemaphoreEntry *)msg->entry1;
  105.     se2 = (struct SemaphoreEntry *)msg->entry2;
  106.     col1 = msg->sort_type & MUIV_NList_TitleMark_ColMask;
  107.     col2 = msg->sort_type2 & MUIV_NList_TitleMark2_ColMask;
  108.  
  109.     if (msg->sort_type == MUIV_NList_SortType_None) return 0;
  110.  
  111.     if (msg->sort_type & MUIV_NList_TitleMark_TypeMask) {
  112.         cmp = semalist_cmp2colfunc(se2, se1, col1);
  113.     } else {
  114.         cmp = semalist_cmp2colfunc(se1, se2, col1);
  115.     }
  116.  
  117.     if (cmp != 0 || col1 == col2) return cmp;
  118.  
  119.     if (msg->sort_type2 & MUIV_NList_TitleMark2_TypeMask) {
  120.         cmp = semalist_cmp2colfunc(se2, se1, col2);
  121.     } else {
  122.         cmp = semalist_cmp2colfunc(se1, se2, col2);
  123.     }
  124.  
  125.     return cmp;
  126. }
  127.  
  128. MakeHook(semalist_cmp2hook, semalist_cmp2func);
  129.  
  130. static void ReceiveList( void (* callback)( struct SemaphoreEntry *se, void *userData ),
  131.                          void *userData )
  132. {
  133.     struct SemaphoreEntry *se;
  134.  
  135.     if (se = tbAllocVecPooled(globalPool, sizeof(struct SemaphoreEntry))) {
  136.         if (SendDaemon("GetSemList")) {
  137.             while (ReceiveDecodedEntry((UBYTE *)se, sizeof(struct SemaphoreEntry))) {
  138.                 callback(se, userData);
  139.             }
  140.         }
  141.  
  142.         tbFreeVecPooled(globalPool, se);
  143.     }
  144. }
  145.  
  146. static void IterateList( void (* callback)( struct SemaphoreEntry *se, void *userData ),
  147.                          void *userData )
  148. {
  149.     struct SignalSemaphore *ss;
  150.     struct MinList tmplist;
  151.     struct SemaphoreEntry *se, *_se;
  152.  
  153.     NewList((struct List *)&tmplist);
  154.  
  155.     Forbid();
  156.  
  157.     ITERATE_LIST(&SysBase->SemaphoreList, struct SignalSemaphore *, ss) {
  158.         if (se = AllocVec(sizeof(struct SemaphoreEntry), MEMF_PUBLIC)) {
  159.             se->se_Addr = ss;
  160.  
  161.             _snprintf(se->se_Address, sizeof(se->se_Address), "$%08lx", ss);
  162.             stccpy(se->se_Name, nonetest (ss->ss_Link.ln_Name), sizeof(se->se_Name));
  163.             _snprintf(se->se_Pri, sizeof(se->se_Pri), "%4ld", ss->ss_Link.ln_Pri);
  164.             _snprintf(se->se_NestCount, sizeof(se->se_NestCount), "%4ld", ss->ss_NestCount);
  165.             _snprintf(se->se_QueueCount, sizeof(se->se_QueueCount), "%4ld", ss->ss_QueueCount);
  166.             if (ss->ss_Owner) {
  167.                 GetTaskName(ss->ss_Owner, se->se_Owner, sizeof(se->se_Owner));
  168.             } else {
  169.                 stccpy(se->se_Owner, "---", sizeof(se->se_Owner));
  170.             }
  171.  
  172.             AddTail((struct List *)&tmplist, (struct Node *)se);
  173.         }
  174.     }
  175.  
  176.     Permit();
  177.  
  178.     ITERATE_CHANGING_LIST(&tmplist, struct SemaphoreEntry *, se, _se) {
  179.         callback(se, userData);
  180.         FreeVec(se);
  181.     }
  182. }
  183.  
  184. static void UpdateCallback( struct SemaphoreEntry *se,
  185.                             void *userData )
  186. {
  187.     struct SemaphoresCallbackUserData *ud = (struct SemaphoresCallbackUserData *)userData;
  188.  
  189.     InsertSortedEntry(ud->ud_List, se);
  190.     ud->ud_Count++;
  191. }
  192.  
  193. static void PrintCallback( struct SemaphoreEntry *se,
  194.                            void *userData )
  195. {
  196.     PrintFOneLine((BPTR)userData, " %s %-30s %4s %4s %5s %s\n", se->se_Address, se->se_Name, se->se_Pri, se->se_NestCount, se->se_QueueCount, se->se_Owner);
  197. }
  198.  
  199. static void SendCallback( struct SemaphoreEntry *se,
  200.                           void *userData )
  201. {
  202.     SendEncodedEntry((UBYTE *)se, sizeof(struct SemaphoreEntry));
  203. }
  204.  
  205. static ULONG __saveds mNew( struct IClass *cl,
  206.                             Object *obj,
  207.                             struct opSet *msg )
  208. {
  209.     APTR semlist, semtext, semcount, updateButton, printButton, obtainButton, releaseButton, removeButton, priorityButton, exitButton;
  210.  
  211.     if (obj = (Object *)DoSuperNew(cl, obj,
  212.         MUIA_HelpNode, SemaphoresText,
  213.         MUIA_Window_ID, MakeID('S','E','M','A'),
  214.         WindowContents, VGroup,
  215.  
  216.             Child, semlist = MyNListviewObject(MakeID('S','E','L','V'), "BAR,BAR,BAR P=" MUIX_R ",BAR P=" MUIX_C ",BAR P=" MUIX_C ",BAR", &semalist_con2hook, &semalist_des2hook, &semalist_dsp2hook, &semalist_cmp2hook, TRUE),
  217.             Child, MyBelowListview(&semtext, &semcount),
  218.  
  219.             Child, MyVSpace(4),
  220.  
  221.             Child, HGroup, MUIA_Group_SameSize, TRUE,
  222.                 Child, updateButton   = MakeButton(txtUpdate),
  223.                 Child, printButton    = MakeButton(txtPrint),
  224.                 Child, obtainButton   = MakeButton(txtObtain),
  225.                 Child, releaseButton  = MakeButton(txtRelease),
  226.                 Child, removeButton   = MakeButton(txtRemove),
  227.                 Child, priorityButton = MakeButton(txtPriority),
  228.                 Child, exitButton     = MakeButton(txtExit),
  229.             End,
  230.         End,
  231.         TAG_MORE, msg->ops_AttrList))
  232.     {
  233.         struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  234.         APTR parent;
  235.  
  236.         swd->swd_SemaphoreList = semlist;
  237.         swd->swd_SemaphoreText = semtext;
  238.         swd->swd_SemaphoreCount = semcount;
  239.         swd->swd_ObtainButton = obtainButton;
  240.         swd->swd_ReleaseButton = releaseButton;
  241.         swd->swd_RemoveButton = removeButton;
  242.         swd->swd_PriorityButton = priorityButton;
  243.  
  244.         parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);
  245.  
  246.         set(obj, MUIA_Window_Title, MyGetWindowTitle("SEMAPHORES", swd->swd_Title, sizeof(swd->swd_Title)));
  247.         set(obj, MUIA_Window_ActiveObject, semlist);
  248.         set(obtainButton, MUIA_Disabled, TRUE);
  249.         set(releaseButton, MUIA_Disabled, TRUE);
  250.         set(removeButton, MUIA_Disabled, TRUE);
  251.         set(priorityButton, MUIA_Disabled, TRUE);
  252.  
  253.         DoMethod(parent,         MUIM_Window_AddChildWindow, obj);
  254.         DoMethod(obj,            MUIM_Notify, MUIA_Window_CloseRequest, TRUE,           MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
  255.         DoMethod(semlist,        MUIM_Notify, MUIA_NList_Active,        MUIV_EveryTime, obj,                     1, MUIM_SemaphoresWin_ListChange);
  256.         DoMethod(updateButton,   MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_SemaphoresWin_Update);
  257.         DoMethod(printButton,    MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_SemaphoresWin_Print);
  258.         DoMethod(obtainButton,   MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_SemaphoresWin_Obtain);
  259.         DoMethod(releaseButton,  MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_SemaphoresWin_Release);
  260.         DoMethod(removeButton,   MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_SemaphoresWin_Remove);
  261.         DoMethod(priorityButton, MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_SemaphoresWin_Priority);
  262.         DoMethod(exitButton,     MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
  263.         DoMethod(semlist,        MUIM_NList_Sort3, MUIV_NList_Sort3_SortType_1, MUIV_NList_SortTypeAdd_None, MUIV_NList_Sort3_SortType_Both);
  264.     }
  265.  
  266.     return (ULONG)obj;
  267. }
  268.  
  269. static ULONG __saveds mDispose( struct IClass *cl,
  270.                                 Object *obj,
  271.                                 struct opSet *msg )
  272. {
  273.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  274.  
  275.     set(obj, MUIA_Window_Open, FALSE);
  276.     DoMethod(swd->swd_SemaphoreList, MUIM_NList_Clear);
  277.  
  278.     return (DoSuperMethodA(cl, obj, msg));
  279. }
  280.  
  281. static ULONG __saveds mUpdate( struct IClass *cl,
  282.                                Object *obj,
  283.                                Msg msg )
  284. {
  285.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  286.     struct SemaphoresCallbackUserData ud;
  287.  
  288.     ApplicationSleep(TRUE);
  289.     set(swd->swd_SemaphoreList, MUIA_NList_Quiet, TRUE);
  290.     DoMethod(swd->swd_SemaphoreList, MUIM_NList_Clear);
  291.  
  292.     ud.ud_List = swd->swd_SemaphoreList;
  293.     ud.ud_Count = 0;
  294.  
  295.     if (clientstate) {
  296.         ReceiveList(UpdateCallback, &ud);
  297.     } else {
  298.         IterateList(UpdateCallback, &ud);
  299.     }
  300.  
  301.     SetCountText(swd->swd_SemaphoreCount, ud.ud_Count);
  302.     MySetContents(swd->swd_SemaphoreText, "");
  303.  
  304.     set(swd->swd_SemaphoreList, MUIA_NList_Quiet, FALSE);
  305.     set(swd->swd_ObtainButton, MUIA_Disabled, TRUE);
  306.     set(swd->swd_ReleaseButton, MUIA_Disabled, TRUE);
  307.     set(swd->swd_RemoveButton, MUIA_Disabled, TRUE);
  308.     set(swd->swd_PriorityButton, MUIA_Disabled, TRUE);
  309.     ApplicationSleep(FALSE);
  310.  
  311.     return 0;
  312. }
  313.  
  314. static ULONG __saveds mPrint( struct IClass *cl,
  315.                               Object *obj,
  316.                               Msg msg )
  317. {
  318.     PrintSemaphores(NULL);
  319.  
  320.     return 0;
  321. }
  322.  
  323. static ULONG __saveds mObtain( struct IClass *cl,
  324.                                Object *obj,
  325.                                Msg msg )
  326. {
  327.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  328.     struct SemaphoreEntry *se;
  329.  
  330.     if (se = (struct SemaphoreEntry *)GetActiveEntry(swd->swd_SemaphoreList)) {
  331.         if (MyRequest(msgYesNo, msgWantToObtainSemaphore, se->se_Name)) {
  332.             MyDoCommand("ObtainSemaphore %s", se->se_Address);
  333.             DoMethod(obj, MUIM_SemaphoresWin_Update);
  334.         }
  335.     }
  336.  
  337.     return 0;
  338. }
  339.  
  340. static ULONG __saveds mRelease( struct IClass *cl,
  341.                                 Object *obj,
  342.                                 Msg msg )
  343. {
  344.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  345.     struct SemaphoreEntry *se;
  346.  
  347.     if (se = (struct SemaphoreEntry *)GetActiveEntry(swd->swd_SemaphoreList)) {
  348.         LONG nest;
  349.  
  350.         if (IsDec(se->se_NestCount, &nest) && nest > 0) {
  351.             if (MyRequest(msgYesNo, msgWantToReleaseSemaphore, se->se_Name)) {
  352.                 MyDoCommand("ReleaseSemaphore %s", se->se_Address);
  353.                 DoMethod(obj, MUIM_SemaphoresWin_Update);
  354.             }
  355.         } else {
  356.             MyRequest(msgErrorContinue, msgNestCountIsZero);
  357.         }
  358.     }
  359.  
  360.     return 0;
  361. }
  362.  
  363. static ULONG __saveds mRemove( struct IClass *cl,
  364.                                Object *obj,
  365.                                Msg msg )
  366. {
  367.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  368.     struct SemaphoreEntry *se;
  369.  
  370.     if (se = (struct SemaphoreEntry *)GetActiveEntry(swd->swd_SemaphoreList)) {
  371.         if (MyRequest(msgYesNo, msgWantToRemoveSemaphore, se->se_Name)) {
  372.             MyDoCommand("RemoveSemaphore %s", se->se_Address);
  373.             DoMethod(obj, MUIM_SemaphoresWin_Update);
  374.         }
  375.     }
  376.  
  377.     return 0;
  378. }
  379.  
  380. static ULONG __saveds mPriority( struct IClass *cl,
  381.                                  Object *obj,
  382.                                  Msg msg )
  383. {
  384.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  385.     struct SemaphoreEntry *se;
  386.  
  387.     if (se = (struct SemaphoreEntry *)GetActiveEntry(swd->swd_SemaphoreList)) {
  388.         LONG pri;
  389.  
  390.         pri = atol(se->se_Pri);
  391.         if (GetPriority(se->se_Name, &pri)) {
  392.             if (MyDoCommand("SetPriority SEMAPHORE \"%s\" %ld", se->se_Name, pri)) {
  393.                 _snprintf(se->se_Pri, sizeof(se->se_Pri), "%4ld", pri);
  394.                 RedrawActiveEntry(swd->swd_SemaphoreList);
  395.             }
  396.         }
  397.     }
  398.  
  399.     return 0;
  400. }
  401.  
  402. static ULONG __saveds mListChange( struct IClass *cl,
  403.                                    Object *obj,
  404.                                    Msg msg )
  405. {
  406.     struct SemaphoresWinData *swd = INST_DATA(cl, obj);
  407.     struct SemaphoreEntry *se;
  408.  
  409.     if (se = (struct SemaphoreEntry *)GetActiveEntry(swd->swd_SemaphoreList)) {
  410.         MySetContents(swd->swd_SemaphoreText, "%s \"%s\"", se->se_Address, se->se_Name);
  411.         set(swd->swd_ObtainButton, MUIA_Disabled, FALSE);
  412.         set(swd->swd_ReleaseButton, MUIA_Disabled, FALSE);
  413.         set(swd->swd_RemoveButton, MUIA_Disabled, FALSE);
  414.         set(swd->swd_PriorityButton, MUIA_Disabled, FALSE);
  415.     }
  416.  
  417.     return 0;
  418. }
  419.  
  420. ULONG __asm __saveds SemaphoresWinDispatcher( register __a0 struct IClass *cl,
  421.                                               register __a2 Object *obj,
  422.                                               register __a1 Msg msg )
  423. {
  424.     switch (msg->MethodID) {
  425.         case OM_NEW:                        return (mNew(cl, obj, (APTR)msg));
  426.         case OM_DISPOSE:                    return (mDispose(cl, obj, (APTR)msg));
  427.         case MUIM_SemaphoresWin_Update:     return (mUpdate(cl, obj, (APTR)msg));
  428.         case MUIM_SemaphoresWin_Print:      return (mPrint(cl, obj, (APTR)msg));
  429.         case MUIM_SemaphoresWin_Obtain:     return (mObtain(cl, obj, (APTR)msg));
  430.         case MUIM_SemaphoresWin_Release:    return (mRelease(cl, obj, (APTR)msg));
  431.         case MUIM_SemaphoresWin_Remove:     return (mRemove(cl, obj, (APTR)msg));
  432.         case MUIM_SemaphoresWin_Priority:   return (mPriority(cl, obj, (APTR)msg));
  433.         case MUIM_SemaphoresWin_ListChange: return (mListChange(cl, obj, (APTR)msg));
  434.     }
  435.  
  436.     return (DoSuperMethodA(cl, obj, msg));
  437. }
  438.  
  439. void PrintSemaphores( char *filename )
  440. {
  441.     BPTR handle;
  442.  
  443.     if (handle = HandlePrintStart(filename)) {
  444.         PrintFOneLine(handle, "\n  Address  Name                            Pri Nest Queue Owner\n\n");
  445.         IterateList(PrintCallback, (void *)handle);
  446.     }
  447.  
  448.     HandlePrintStop();
  449. }
  450.  
  451. void SendSemList( void )
  452. {
  453.     IterateList(SendCallback, NULL);
  454. }
  455.  
  456.